

def analysis_daytrend(daytrend: list):
    """
    根据个股日K，简单分析

    :param daytrend: 日K列表
    :return:
        【'Too little'】 - 日K 数据太少
        【float】 - 推荐指数（0.5），如果不是浮动型，说明错误
    """
    # print(f'需要分析的日K列表：{daytrend}')
    daytrend_totalNum = len(daytrend)  # 总k线数
    print(f'日K总数：{daytrend_totalNum}')
    if daytrend_totalNum < 20:
        # 如果总K线数小于30，可能是近期上市的新股，数据不足无法分析
        print(f'日K 数据太少！')
        return 'Too little'

    # 将列表处理成可分析的字典
    daytrend_dict = {}  # 分析需要的字典
    index = 1  # 位置
    for noe in daytrend:
        date, highest, minimum = noe.split(',')
        daytrend_dict[str(index)] = {
            'date': date,
            'highest': float(highest),  # 价格转换为浮点型，排序是才能正确
            'minimum': float(minimum),   # 价格转换为浮点型，排序是才能正确
        }
        index += 1
    # print(f'analysis_daytrend 处理完的字典：{daytrend_dict}')

    # --！！！_总权重：0.9_！！！--
    total_weight = []  # 存储总权重

    # --判断最高点的位置------------------------------------------------
    highestPOS_weight = 0.3  # 最高点位置：占权重0.1
    noWeight_pos = int(daytrend_totalNum * 0.1)  # 如果最高位置超过前90%, 则无权重
    yesWeight_pos = daytrend_totalNum - noWeight_pos  # 有权重的位置，即最高在1 - yesWeight_pos之间都有权重，越靠前，权重越高
    print(f'超过 {yesWeight_pos} 无权重！')
    # 每个位置占的权重
    aWeight = highestPOS_weight / yesWeight_pos
    print(f'每个有权重位置占比：{aWeight}')
    # 按照最高价格倒序排序
    desc_highest = sorted(daytrend_dict.items(), key=lambda kv: (kv[1]['highest'], kv[0]), reverse=True)
    # print(f'按照最高价格倒序排序: {desc_highest}')
    highest_pos = int(desc_highest[0][0])  # 本时间段最高的位置
    print(f"本时间段最高点位置：{highest_pos}")
    highest_price = desc_highest[0][1]["highest"]  # 本时间段最高价
    print(f'本时间段最高价：{highest_price}')
    # 根据最高点位置给出权重。
    # 越靠前，权重越高。即：本时间段最高点位置 == 1。权重 = 0.1, 以此类推。
    if highest_pos > yesWeight_pos:
        # 如果超出有权重范围的位置，权重直接等于0
        highest_Weight = 0.0
    else:
        highest_Weight = (yesWeight_pos - highest_pos + 1) * aWeight
    print(f'最高点位置权重：{highest_Weight}')

    total_weight.append(highest_Weight)
    # --判断最高点的位置------------------------------------------------

    # --判断最最低的位置------------------------------------------------
    minimumPOS_weight = 0.3  # 最低点位置：占权重0.1
    noWeight_pos = int(daytrend_totalNum * 0.1)  # 如果最低位置超过后90%, 则无权重
    yesWeight_pos = daytrend_totalNum - noWeight_pos
    print(f'未超过 {noWeight_pos} 无权重！')
    # 每个位置占的权重
    aWeight = minimumPOS_weight / yesWeight_pos
    print(f'每个有权重位置占比：{aWeight}')
    # 按照最低价格倒序排序
    desc_minimum = sorted(daytrend_dict.items(), key=lambda kv: (kv[1]['minimum'], kv[0]))
    # print(f'按照最低价格升序排序: {desc_minimum}')
    minimum_pos = int(desc_minimum[0][0])  # 本时间段最低的位置
    print(f"本时间段最低点位置：{minimum_pos}")
    minimum_price = desc_minimum[0][1]["minimum"]  # 本时间段最低价
    print(f'本时间段最低价：{minimum_price}')
    # 根据最高低点位置给出权重。
    # 越靠后，权重越高。即：本时间段最低点位置 == 总日K数。权重 = 0.1, 以此类推。
    if minimum_pos <= noWeight_pos:
        minimum_Weight = 0.0
    else:
        minimum_Weight = (minimum_pos - noWeight_pos) * aWeight
    print(f'最低点位置权重：{minimum_Weight}')

    total_weight.append(minimum_Weight)
    # --判断最最低的位置------------------------------------------------

    latest_minimumPrice_weight = 0.4
    multiple = 3.0  # 如果最新最低价与最低价差3倍，直接无权重
    # --判断最新最低价与最低价差距------------------------------------------------
    # 如果：最新的最低价 = 最低价。权重0.1
    # 如果：最新的最低价 >= 最低价。权重0.1起，越大权重越低，最低0.0
    latest_minimumPrice = daytrend_dict[str(daytrend_totalNum)]['minimum']  # 最新的最低
    print(f'---------\n最新的最低：{latest_minimumPrice}\n最低：{minimum_price}')
    if float(latest_minimumPrice) != float(minimum_price):
        amultiple_weight = latest_minimumPrice_weight / multiple  # 每大1倍的权重需要减去
        print(f'每大 1 倍的权重需要减去: {amultiple_weight}')
        if float(latest_minimumPrice) > float(minimum_price):
            # 权重0.1起，越大权重越低，最低0.0
            # 大于最低价的 3倍，直接 0.0
            rate = (float(latest_minimumPrice) - float(minimum_price)) / float(minimum_price)  # 最新的最低价比最低价多
            print(f'最新的最低价比最低价多 {rate} 倍')
            if rate > multiple:
                latest_minimumPrice_weight = 0.0
            else:
                latest_minimumPrice_weight -= rate * amultiple_weight
    # 最终最新的最低与最低的权重
    print(f'最终最新的最低与最低的权重: {latest_minimumPrice_weight}')

    total_weight.append(latest_minimumPrice_weight)
    # --判断最新最低价与最低价差距------------------------------------------------

    print(f'最终波浪推荐指数：{sum(total_weight)}')
    # 占比不超过0.5
    if sum(total_weight) > 0.5:
        return 0.5
    else:
        return sum(total_weight)


def stock_rating(jjheld_info: list, date):
    """
    统计基金持仓，并生成个股推荐指数

    :param jjheld_info: 基金持有信息
    :param date: 当前日期（2021-08-03）
    :return:
        【'Time out'】 - 超时
        【'Network error'】 - 网络错误
        【dict】 - 字典
            {
                '603259':{
                    'recommendIndex': 0.0,
                    'recomStockInfo': [股票简称: str, 股票代码: str, 被持有数: int, 被持有股（万股）: float],
                    'beHoldJJ': [
                        (基金名称: str, 持有该股票（万股）: str, 占基金净值比（'6.00%'）: str),
                        ......
                    ],
                },
                ......
            }
    """
    # print(f'需要处理的基金持仓: {jjheld_info}')
    data = {}  # 存储分析完的数据
    # tempStock = []  # 存储股票信息
    # 统计基金持仓
    for noe in jjheld_info:
        jjinfo = noe['jjInfo']
        # 遍历基金持仓
        for stock in noe['jjHeld']:
            # print(f'持有信息：\t{stock}')
            # 判断股票代码是否已经记录, 无记录新增一条记录
            if stock[2] not in data.keys():
                print(f'未记录 {stock[2]} ！')
                # 增加一条信息
                data[str(stock[2])] = {
                    'recommendIndex': 0.0,
                    'recomStockInfo': [stock[3], stock[2], 0, 0],
                    'beHoldJJ': []
                }
            # 记录被持有的基金
            beHoldjjname = jjinfo[1]  # 被持有基金名称
            beHoldshare = stock[-2].replace(',', '')  # 基金持有份额（万股）, replace去掉数字分隔符‘,’
            beHoldrate = stock[-3]  # 占基金净值比例
            data[str(stock[2])]['beHoldJJ'].append((beHoldjjname, beHoldshare, beHoldrate))
            # 自增被持数和持有股份
            data[str(stock[2])]['recomStockInfo'][-1] += float(beHoldshare)  # 持有股份
            data[str(stock[2])]['recomStockInfo'][-2] += 1  # 持有数
            # 推荐指数： 最大1.0 最后显示时，按照推荐指数倒序显示。
            # 推荐指数的权重：
            #   被持有数：占比0.5
            #       每增加一只被持基金，指数增加0.00001
            #   日K分析：占比0.5
            data[str(stock[2])]['recommendIndex'] += 0.01
            # 如果指数不超过0.5
            if data[str(stock[2])]['recommendIndex'] > 0.5:
                data[str(stock[2])]['recommendIndex'] = 0.5

    from Internet import get_stock_daytrend  # 导入获取日K函数
    from time import mktime, strptime, strftime, localtime, sleep

    # --计算90天前的日期
    # print(f'当前日期：{date}')
    # 将日期字符串转换为时间戳
    stamp = mktime(strptime(date, '%Y-%m-%d'))
    # 计算90天前的日期, 一天 86400s。用当前时间戳 - 90 * 86400 = 90天前的时间戳
    day90_stamp = stamp - 90 * 86400
    # print(f"90天前的时间戳：{day90_stamp}")
    # 将时间戳转换为字符串日期
    ago60date = strftime('%Y%m%d', localtime(day90_stamp))
    # print(f'90天前的日期：{ago60date}')

    # 分析个股推荐指数
    for code in data.keys():
        # 只有被持有超过 10 的才进行日K分析
        if not data[code]['recomStockInfo'][-2] > 10:
            print(f'{code} 被持有未超过 10, 跳过!')
            continue
        print(f'获取 {code} 日K！！！')
        # 获取日K
        daykline = get_stock_daytrend(code, beg=ago60date)
        if not isinstance(daykline, list):
            # 如果返回不是列表，说明访问出错
            if daykline != 'TryAll error':
                return daykline
            else:
                # secid错误，或者是港股, 给空列表
                daykline = []
        # 获取日K成功
        recomindex = analysis_daytrend(daykline)  # 推荐指数
        if isinstance(recomindex, float):
            print(f' {code} 推荐指数增加：{recomindex}')
            data[code]['recommendIndex'] += recomindex

    # 个股推荐指数分析完成
    return data
